package com.pig4cloud.pig.ads.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.ads.exception.CommentException;
import com.pig4cloud.pig.ads.pig.mapper.AdAwemeBannedMapper;
import com.pig4cloud.pig.ads.pig.mapper.AdvertiserMapper;
import com.pig4cloud.pig.ads.pig.mapper.TtAccesstokenMapper;
import com.pig4cloud.pig.ads.service.AdAccountService;
import com.pig4cloud.pig.ads.service.AdAwemeBannedService;
import com.pig4cloud.pig.ads.service.TtCommentApiService;
import com.pig4cloud.pig.api.dto.AdAwemeBannedDto;
import com.pig4cloud.pig.api.entity.*;
import com.pig4cloud.pig.api.vo.AdAccountVo;
import com.pig4cloud.pig.api.vo.AdAwemeBannedVo;
import com.pig4cloud.pig.api.vo.TtResultVo;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.enums.PlatformTypeEnum;
import com.pig4cloud.pig.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AdAwemeBannedServiceImpl extends ServiceImpl<AdAwemeBannedMapper, AdAwemeBannedEntity> implements AdAwemeBannedService {

	private static final Pattern ILLEGAL_AWEME_PATTERN = Pattern.compile("^[0][0-9]*$");

	private final AdAwemeBannedMapper adAwemeBannedMapper;

	private final TtCommentApiService ttCommentApiService;

	private final AdvertiserMapper advertiserMapper;

	private final TtAccesstokenMapper ttAccesstokenMapper;

	//	private final AdvService advService;
	private final AdAccountService adAccountService;

	/**
	 * 屏蔽用户列表
	 *
	 * @param req
	 * @return
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	@Override
	public Page<AdAwemeBannedEntity> getAwemePage(AdAwemeBannedVo req) {
		// 获取当前账号下广告账户列表
//		Set<String> advertiserIds = advService.getAccountList(Integer.parseInt(PlatformTypeEnum.TT.getValue()), null).stream().map(AdAccount::getAdvertiserId).collect(Collectors.toSet());
		Set<String> advertiserIds = adAccountService.getAccountsByAuthorize(new AdAccountVo().setMediaCode(PlatformTypeEnum.TT.getValue())).stream().map(AdAccount::getAdvertiserId).collect(Collectors.toSet());
		if (CollectionUtils.isEmpty(advertiserIds)) {
			return new Page<AdAwemeBannedEntity>().setTotal(0).setCurrent(req.getCurrent()).setSize(req.getSize()).setRecords(Collections.emptyList());
		}
		LambdaQueryWrapper<AdAwemeBannedEntity> queryWrapper = Wrappers.<AdAwemeBannedEntity>lambdaQuery()
				.select(AdAwemeBannedEntity::getId, AdAwemeBannedEntity::getAweme_id, AdAwemeBannedEntity::getAweme_name, AdAwemeBannedEntity::getBanned_type, AdAwemeBannedEntity::getNickname_keyword,
						AdAwemeBannedEntity::getAdvertiser_id, AdAwemeBannedEntity::getAdvertiser_name, AdAwemeBannedEntity::getCreate_date, AdAwemeBannedEntity::getUpdate_date)
				.in(!advertiserIds.isEmpty(), AdAwemeBannedEntity::getAdvertiser_id, advertiserIds).eq(AdAwemeBannedEntity::getIs_deleted, 0)
				.like(StringUtils.isNoneEmpty(req.getAdvertiserName()), AdAwemeBannedEntity::getAdvertiser_name, req.getAdvertiserName())
				.like(StringUtils.isNoneEmpty(req.getNicknameKeyword()), AdAwemeBannedEntity::getNickname_keyword, req.getNicknameKeyword())
				.like(StringUtils.isNoneEmpty(req.getAwemeId()), AdAwemeBannedEntity::getAweme_id, req.getAwemeId())
				.orderByDesc(AdAwemeBannedEntity::getCreate_date);
		return baseMapper.selectPage(req, queryWrapper);
	}

	/**
	 * 添加屏蔽用户
	 *
	 * @param req
	 */
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
	@Override
	public void addAweme(AdAwemeBannedVo req) {
		String advertiserId = req.getAdvertiserId();
		String bannedType = req.getBannedType();
		if ("CUSTOM_TYPE".equals(bannedType)) { // 自定义规则，根据昵称关键词屏蔽
			List<String> keywords = req.getKeywords();
			if (keywords.stream().map(AdAwemeBannedServiceImpl::getKeywordLength).anyMatch(e -> e == 0 || e > 40)) {
				throw new CommentException(CommonConstants.FAIL, "屏蔽用户关键词不能为空并且长度不允许超过40");
			}
			if (keywords.stream().distinct().count() != keywords.size()) {
				throw new CommentException(CommonConstants.FAIL, "提交的多个屏蔽用户关键词有重复的内容");
			}
			if (this.count(Wrappers.<AdAwemeBannedEntity>lambdaQuery().eq(AdAwemeBannedEntity::getAdvertiser_id, req.getAdvertiserId()).eq(AdAwemeBannedEntity::getIs_deleted, 0).in(AdAwemeBannedEntity::getBanned_type, bannedType)) >= 5000) {
				throw new IllegalStateException("当前广告账户屏蔽昵称关键词数量已超过5000");
			}
			// 校验屏蔽昵称关键字是否存在
			Set<String> existsSet = this.list(Wrappers.<AdAwemeBannedEntity>lambdaQuery().select(AdAwemeBannedEntity::getNickname_keyword).eq(AdAwemeBannedEntity::getAdvertiser_id, req.getAdvertiserId()).in(AdAwemeBannedEntity::getBanned_type, bannedType)
					.in(AdAwemeBannedEntity::getNickname_keyword, keywords).eq(AdAwemeBannedEntity::getIs_deleted, 0)).stream().map(AdAwemeBannedEntity::getNickname_keyword).collect(Collectors.toSet());
			if (!existsSet.isEmpty()) {
				throw new CommentException(CommonConstants.FAIL, "屏蔽用户关键词“" + String.join(",", existsSet) + "”已存在");
			}
			// 保存屏蔽用户信息
			this.saveBatch(keywords.stream().map(text -> new AdAwemeBannedEntity().setBanned_type(bannedType).setNickname_keyword(text).setAdvertiser_id(advertiserId).setAdvertiser_name(req.getAdvertiserName())
					.setCreate_date(new Date()).setUpdate_date(new Date())).collect(Collectors.toList()));
			//调用接口
			String accessToken = findAccessToken(advertiserId);
			TtResultVo result = ttCommentApiService.awemeBannedCreate(Long.parseLong(advertiserId), accessToken, bannedType, null, keywords);
			if (!result.getSuccess()) { // 调用失败
				throw new CommentException(CommonConstants.FAIL, result.getMessage());
			}
		} else if ("AWEME_TYPE".equals(bannedType)) { // 根据抖音id屏蔽
			List<String> awemeIds = req.getAwemeIds();
			if (awemeIds.stream().anyMatch(e -> null == e || e.length() == 0 || e.length() > 20 || ILLEGAL_AWEME_PATTERN.matcher(e).find())) {
				throw new CommentException(CommonConstants.FAIL, "屏蔽抖音号不能为空并且长度不允许超过20，如果是纯数字则不可以0开头");
			}
			if (awemeIds.stream().distinct().count() != awemeIds.size()) {
				throw new CommentException(CommonConstants.FAIL, "提交的多个抖音账号有重复的内容");
			}
			if (this.count(Wrappers.<AdAwemeBannedEntity>lambdaQuery().eq(AdAwemeBannedEntity::getAdvertiser_id, req.getAdvertiserId()).eq(AdAwemeBannedEntity::getIs_deleted, 0).in(AdAwemeBannedEntity::getBanned_type, bannedType)) >= 5000) {
				throw new IllegalStateException("当前广告账户屏蔽抖音账号数量已超过5000");
			}
			// 校验屏蔽抖音账号是否存在
			Set<String> existsSet = this.list(Wrappers.<AdAwemeBannedEntity>lambdaQuery().select(AdAwemeBannedEntity::getAweme_id).eq(AdAwemeBannedEntity::getAdvertiser_id, req.getAdvertiserId()).in(AdAwemeBannedEntity::getBanned_type, bannedType)
					.in(AdAwemeBannedEntity::getAweme_id, awemeIds).eq(AdAwemeBannedEntity::getIs_deleted, 0)).stream().map(AdAwemeBannedEntity::getAweme_id).collect(Collectors.toSet());
			if (!existsSet.isEmpty()) {
				throw new CommentException(CommonConstants.FAIL, "抖音号“" + String.join(",", existsSet) + "”已存在");
			}
			// 保存屏蔽用户信息
			this.saveBatch(awemeIds.stream().map(text -> new AdAwemeBannedEntity().setBanned_type(bannedType).setAweme_id(text).setAdvertiser_id(advertiserId).setAdvertiser_name(req.getAdvertiserName())
					.setCreate_date(new Date()).setUpdate_date(new Date())).collect(Collectors.toList()));
			//调用接口
			String accessToken = findAccessToken(advertiserId);
			TtResultVo result = ttCommentApiService.awemeBannedCreate(Long.parseLong(advertiserId), accessToken, bannedType, awemeIds, null);
			if (!result.getSuccess()) { // 调用失败
				throw new CommentException(CommonConstants.FAIL, result.getMessage());
			}
		}
	}

	private static int getKeywordLength(String keyword) {
		if (StringUtils.isEmpty(keyword)) {
			return 0;
		}
		int len = 0;
		for (char c : keyword.toCharArray()) {
			int codeValue = c & 0xffff;
			if (codeValue >= 0x4e00 && codeValue <= 0x9fa5) {
				len += 2;
			} else {
				Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
				if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
						|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
					len += 2;
				} else {
					++len;
				}
			}
		}
		return len;
	}

	/**
	 * 删除屏蔽用户
	 *
	 * @param id
	 */
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
	@Override
	public void deleteAweme(Long id) {
		AdAwemeBannedEntity aweme = this.getOne(Wrappers.<AdAwemeBannedEntity>lambdaQuery().eq(AdAwemeBannedEntity::getId, id).eq(AdAwemeBannedEntity::getIs_deleted, 0));
		if (null == aweme) {
			return;
		}
		// 假删除数据
		this.updateById(new AdAwemeBannedEntity().setId(id).setIs_deleted(1).setUpdate_date(new Date()));

		// 调用接口删除
		String advertiserId = aweme.getAdvertiser_id();
		String bannedType = aweme.getBanned_type();
		String accessToken = findAccessToken(advertiserId);
		if ("CUSTOM_TYPE".equals(bannedType)) { // 自定义规则
			TtResultVo result = ttCommentApiService.awemeBannedDelete(Long.parseLong(advertiserId), accessToken, bannedType, null, aweme.getNickname_keyword());
			if (!result.getSuccess()) { // 调用失败
				throw new CommentException(CommonConstants.FAIL, result.getMessage());
			}
		} else if ("AWEME_TYPE".equals(bannedType)) { // 根据抖音id屏蔽
			TtResultVo result = ttCommentApiService.awemeBannedDelete(Long.parseLong(advertiserId), accessToken, bannedType, aweme.getAweme_id(), null);
			if (!result.getSuccess()) {//调用失败
				throw new CommentException(CommonConstants.FAIL, result.getMessage());
			}
		}
	}


	@Deprecated
	@Override
	public IPage<AdAwemeBannedVo> selectPageList(AdAwemeBannedDto dto) {
//		Integer userId = SecurityUtils.getUser().getId();
		//获取当前账号下 广告账户列表
//		List<String> advertiserIds = advService.getOwnerAdv(userId, PlatformTypeEnum.TT.getValue());
		List<String> advertiserIds = adAccountService.getAccountsByAuthorize(new AdAccountVo().setMediaCode(PlatformTypeEnum.TT.getValue())).stream().map(AdAccount::getAdvertiserId).collect(Collectors.toList());

		if (CollectionUtils.isEmpty(advertiserIds)) {
			return new Page();
		}
		dto.setAdvertiserIds(advertiserIds);
		return adAwemeBannedMapper.selectPageList(dto);
	}

	@Deprecated
	@Override
	@Transactional
	public R addAweme(AdAwemeBannedDto dto) {
		String advertiser_id = dto.getAdvertiser_id();
		//查询token
		String accessToken = findAccessToken(advertiser_id);
		String banned_type = dto.getBanned_type();
		TtResultVo result = null;

		if ("CUSTOM_TYPE".equals(banned_type)) {//自定义规则
			List<String> kewordList = dto.getKeyword_list();//昵称关键词列表
			List<AdAwemeBannedEntity> saveList = new ArrayList<>();
			if (CollectionUtils.isEmpty(kewordList)) {
				return R.failed("关键词不允许为空");
			}
			kewordList = kewordList.stream().distinct().collect(Collectors.toList());
			List<AdAwemeBannedEntity> quaryAwemeList = null;
			for (String keyword : kewordList) {
				quaryAwemeList = baseMapper.selectList(Wrappers.<AdAwemeBannedEntity>query().lambda().eq(AdAwemeBannedEntity::getAdvertiser_id, advertiser_id).eq(AdAwemeBannedEntity::getIs_deleted, CommonConstants.STATUS_NORMAL).eq(AdAwemeBannedEntity::getNickname_keyword, keyword));
				if (CollectionUtils.isNotEmpty(quaryAwemeList)) {
					continue;
				}
				AdAwemeBannedEntity bannedEntity = new AdAwemeBannedEntity();
				BeanUtils.copyProperties(dto, bannedEntity);
				bannedEntity.setNickname_keyword(keyword);
				saveList.add(bannedEntity);
			}
			//批量保存
			if (saveList.size() > 0) {
				Integer i = adAwemeBannedMapper.batchInsertAweme(saveList);
				if (i <= 0) {
					return R.failed("数据库保存失败");
				}
			}
			//调用接口
			result = ttCommentApiService.awemeBannedCreate(Long.parseLong(advertiser_id), accessToken, banned_type, null, kewordList);
		} else {//根据抖音id屏蔽
			String awemeId = dto.getAweme_id();
			if (StringUtils.isEmpty(awemeId)) {
				return R.failed("抖音id不允许为空");
			}

			List awemeList = baseMapper.selectList(Wrappers.<AdAwemeBannedEntity>query().lambda().eq(AdAwemeBannedEntity::getAdvertiser_id, advertiser_id).eq(AdAwemeBannedEntity::getIs_deleted, CommonConstants.STATUS_NORMAL).eq(AdAwemeBannedEntity::getAweme_id, awemeId));
			if (CollectionUtils.isNotEmpty(awemeList)) {
				return R.failed("当前账号对应的抖音号已添加");
			}
			AdAwemeBannedEntity entity = new AdAwemeBannedEntity();
			BeanUtils.copyProperties(dto, entity);
			Integer r = adAwemeBannedMapper.insertAweme(entity);
			if (r <= 0) {
				return R.failed("数据库保存失败");
			}
			//调用接口
			List<String> awemeIds = new ArrayList<>();
			awemeIds.add(dto.getAweme_id());
			result = ttCommentApiService.awemeBannedCreate(Long.parseLong(advertiser_id), accessToken, banned_type, awemeIds, null);
		}
		if (!result.getSuccess()) {//调用失败
			throw new CommentException(CommonConstants.FAIL, result.getMessage());
		}
		return R.ok("", "操作成功");
	}

	@Deprecated
	@Override
	@Transactional
	public R deleteAweme(AdAwemeBannedDto dto) {
		AdAwemeEntity adAwemeEntity = adAwemeBannedMapper.queryAwemeById(dto.getId());
		if (null == adAwemeEntity) {
			return R.failed("未找到记录");
		}
		String advertiser_id = adAwemeEntity.getAdvertiserId();
		Integer r = adAwemeBannedMapper.deleteAwemeById(dto.getId());
		if (r <= 0) {
			return R.failed("数据库删除失败");
		}
		//查询token
		String accessToken = findAccessToken(advertiser_id);
		//调用接口删除
		String banned_type = adAwemeEntity.getBannedType();
		TtResultVo result = null;
		if ("CUSTOM_TYPE".equals(banned_type)) {//自定义规则
			result = ttCommentApiService.awemeBannedDelete(Long.parseLong(advertiser_id), accessToken, banned_type, null, adAwemeEntity.getNicknameKeyword());
		} else {//根据抖音id屏蔽
			result = ttCommentApiService.awemeBannedDelete(Long.parseLong(advertiser_id), accessToken, banned_type, adAwemeEntity.getAwemeId(), null);
		}
		if (!result.getSuccess()) {//调用失败
			throw new CommentException(CommonConstants.FAIL, result.getMessage());
		}
		return R.ok("", "操作成功");
	}

	//查询token
	private String findAccessToken(String advertiser_id) {
		Advertising advertising = advertiserMapper.selectById(advertiser_id);
		if (null == advertising) {
			throw new CommentException(CommonConstants.FAIL, "未找到对应广告账户");
		}
		//查询accesstoken获取token
		TtAccesstoken token = ttAccesstokenMapper.selectById(advertising.getHousekeeper());
		if (null == token) {
			throw new CommentException(CommonConstants.FAIL, "未找到对应AccessToken");
		}
		return token.getAccessToken();
	}

}
